﻿#region Copyright
// Copyright (c) 2009, Mitchell Humphrey & Co.
// This software is a copyrighted, licensed program which is the
// property of Mitchell Humphrey & Co.  Permission to use, copy
// or distribute this program in any form -- source, executable,
// or otherwise -- is granted only by written license obtained
// from Mitchell Humphrey & Co.  All rights reserved.  No part
// of the publication may be reproduced, stored in a retrieval
// system, or transmitted in any way without written permission
// of Mitchell Humphrey & Co.
#endregion Copyright

#region Revision History

//REVISION HISTORY:
//John Hoven 05/18/2009 Original..
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Microsoft.Crm.Sdk;
using System.Globalization;
using Moq;
using Microsoft.Crm.SdkTypeProxy;
using MitchellHumphrey.Plugins;

namespace MitchellHumphrey.CRM.MHNetCRMTests
{
    [TestFixture]
    public class DateOnlyChangePluginTester
    {
        private Mock<IPluginExecutionContext> context;
        private Mock<ICrmService> crmService;
        private DateOnlyChangePluginCreateUpdateRank150 plugin = null;

        #region Setup/Teardown
        /// <summary>
        ///     Executes at the beginning of each test case. Executed only once per TextFixture  
        /// </summary>
        [SetUp]
        public void Setup()
        {
            context = new Mock<IPluginExecutionContext>(MockBehavior.Strict);
            crmService = new Mock<ICrmService>(MockBehavior.Strict);

            plugin = new DateOnlyChangePluginCreateUpdateRank150(@"<dateOnlyConfiguration>
  <entity name=" + "\"" + @"account" + "\"" + @">
    <attribute name=" + "\"" + @"mhos_datefield1" + "\"" + @" />
    <attribute name=" + "\"" + @"mhos_datefield2" + "\"" + @" />
  </entity> 

  <entity name=" + "\"" + @"mhos_log" + "\"" + @">
    <attribute name=" + "\"" + @"mhos_test1" + "\"" + @" />
    <attribute name=" + "\"" + @"mhos_test2" + "\"" + @" />
  </entity>

</dateOnlyConfiguration>", null);
        }

        #endregion

        [Test]
        public void InitTest()
        {
            Assert.IsTrue(plugin.AttributeDict.Keys.Count == 2);
            Assert.IsTrue(plugin.AttributeDict["mhos_log"].Count() == 2);
            Assert.IsTrue(plugin.AttributeDict["mhos_log"].Contains("mhos_test1"));
            Assert.IsTrue(plugin.AttributeDict["mhos_log"].Contains("mhos_test2"));
        }

        [Test]
        public void TestUserTimeOK()
        {
            // Set up to create crm service wrapper
            context.Setup(c => c.CreateCrmService(It.IsAny<bool>())).Returns(crmService.Object);
            DynamicEntity dyn = new DynamicEntity("account");

            PropertyBag propBag = new PropertyBag();
            propBag["Target"] = dyn;
            context.Setup(c => c.MessageName).Returns(MessageName.Create);
            context.Setup(c => c.InputParameters).Returns(propBag);
            context.Setup(c => c.UserId).Returns(Guid.NewGuid());
            dyn["mhos_datefield1"] = new CrmDateTime("2007-05-01T00:00:00");

            plugin.Execute(context.Object);

            Assert.IsTrue(((CrmDateTime)dyn["mhos_datefield1"]).Value == "2007-05-01T12:00:00Z");
        }

        [Test]
        public void TestUniversalTimeOK()
        {
            // Set up to create crm service wrapper
            context.Setup(c => c.CreateCrmService(It.IsAny<bool>())).Returns(crmService.Object);
            DynamicEntity dyn = new DynamicEntity("account");

            PropertyBag propBag = new PropertyBag();
            propBag["Target"] = dyn;
            context.Setup(c => c.MessageName).Returns(MessageName.Create);
            context.Setup(c => c.InputParameters).Returns(propBag);
            context.Setup(c => c.UserId).Returns(Guid.NewGuid());
            dyn["mhos_datefield1"] = new CrmDateTime("2007-05-01T00:00:00Z");

            RetrieveUserSettingsSystemUserResponse response = new RetrieveUserSettingsSystemUserResponse();
            DynamicEntity userSettings = new DynamicEntity();
            userSettings["timezonecode"] = new CrmNumber(35);
            crmService.Setup(c => c.Execute(It.IsAny<RetrieveUserSettingsSystemUserRequest>())).Returns(response);
            LocalTimeFromUtcTimeResponse response2 = new LocalTimeFromUtcTimeResponse();
            response2.LocalTime = new CrmDateTime("2007-05-01T08:00:00-04:00");
            crmService.Setup(c => c.Execute(It.IsAny<LocalTimeFromUtcTimeRequest>())).Returns(response2);


            plugin.Execute(context.Object);

            Assert.IsTrue(((CrmDateTime)dyn["mhos_datefield1"]).Value == "2007-05-01T12:00:00Z");
        }

        [Test]
        public void TestNoDates()
        {
            // Set up to create crm service wrapper
            context.Setup(c => c.CreateCrmService(It.IsAny<bool>())).Returns(crmService.Object);
            DynamicEntity dyn = new DynamicEntity("account");

            PropertyBag propBag = new PropertyBag();
            propBag["Target"] = dyn;
            context.Setup(c => c.MessageName).Returns(MessageName.Create);
            context.Setup(c => c.InputParameters).Returns(propBag);
            context.Setup(c => c.UserId).Returns(Guid.NewGuid());
            dyn["mhos_test3"] = new CrmNumber(1);
            dyn["mhos_test4"] = "some String";

            plugin.Execute(context.Object);

            Assert.IsTrue(dyn.Properties.Count == 2);
            Assert.IsTrue(((string)dyn["mhos_test4"]) == "some String");
            Assert.IsTrue(((CrmNumber)dyn["mhos_test3"]).Value == 1);
        }

        [Test]
        public void TestMisConfigure()
        {
            // Set up to create crm service wrapper
            context.Setup(c => c.CreateCrmService(It.IsAny<bool>())).Returns(crmService.Object);
            DynamicEntity dyn = new DynamicEntity("account");

            PropertyBag propBag = new PropertyBag();
            propBag["Target"] = dyn;
            context.Setup(c => c.MessageName).Returns(MessageName.Create);
            context.Setup(c => c.InputParameters).Returns(propBag);
            context.Setup(c => c.UserId).Returns(Guid.NewGuid());
            dyn["mhos_datefield1"] = "2007-05-01T00:00:00Z";

            plugin.Execute(context.Object);

            Assert.IsTrue(((string)dyn["mhos_datefield1"]) == "2007-05-01T00:00:00Z");
            Assert.IsTrue(dyn.Properties.Count == 1);
        }

        [Test]
        [ExpectedException(typeof(InvalidPluginExecutionException))]
        public void TestRegistrationInvalid()
        {
            // Set up to create crm service wrapper
            context.Setup(c => c.CreateCrmService(It.IsAny<bool>())).Returns(crmService.Object);
            DynamicEntity dyn = new DynamicEntity("account");

            PropertyBag propBag = new PropertyBag();
            propBag["Target"] = dyn;
            context.Setup(c => c.MessageName).Returns(MessageName.Retrieve);
            context.Setup(c => c.InputParameters).Returns(propBag);
            context.Setup(c => c.UserId).Returns(Guid.NewGuid());
            dyn["mhos_datefield1"] = "2007-05-01T00:00:00Z";

            plugin.Execute(context.Object);

            Assert.IsTrue(((string)dyn["mhos_datefield1"]) == "2007-05-01T00:00:00Z");
            Assert.IsTrue(dyn.Properties.Count == 1);
        }
    }
}
